package com.xiezc.springboot_dht.util;

import com.xiezc.springboot_dht.model.BeString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadFactory;

import static com.xiezc.springboot_dht.util.Const.tokenLievMin;

public class XUtil {
    private static final Logger log = LoggerFactory.getLogger(XUtil.class);
    public static Random random = new Random();
    public static final DefaultThreadFactory defaultThreadFactory = new DefaultThreadFactory("system");
    private static final char[] HEXDIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWZXY".toCharArray();

    /**
     * @return
     */
    public static String getRandomToken() {
        LocalDateTime now = LocalDateTime.now();
        int dayOfYear = now.getDayOfYear();
        int hour = now.getHour();
        int minute = now.getMinute();
        String s1 = dayOfYear + "-" + hour + "-" + minute;
        return s1 + "=" + SHA1(s1 + Const.thisId.getValue());

    }

    public static boolean checkToken(String token) {
        String[] strings = token.split("=");
        if (strings == null || strings.length != 2) {
            return false;
        }
        LocalDateTime now = LocalDateTime.now();
        int dayOfYear = now.getDayOfYear();
        int hour = now.getHour();
        int minute = now.getMinute();
        String[] split = strings[0].split("-");
        if (strings == null || strings.length != 3) {
            return false;
        }
        if (dayOfYear == Integer.valueOf(split[0]) && hour == Integer.valueOf(split[1]) && minute - Integer.valueOf(
            split[2]) < tokenLievMin) {
            String s = strings[0] + "=" + SHA1(strings[0] + Const.thisId.getValue());
            if (!s.equals(strings[1])) {
                return false;
            }
            return true;
        }

        return false;
    }

    public final static String SHA1(String decript) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte[] messageDigest = digest.digest();
            return toHex(messageDigest);
        } catch (NoSuchAlgorithmException e) {
            throw new BeException(e);
        }

    }

    public static String toHex(byte[] bytes) {
        final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
        StringBuilder ret = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
            ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
        }
        return ret.toString();
    }

    /**
     * 获得一个随机的字母
     *
     * @return
     */
    public static char getRandomChar() {
        int i = random.nextInt() % HEXDIGITS.length;
        if (i < 0) {
            i = i * -1;
        }
        return HEXDIGITS[i];
    }

    /**
     * 计算两个Node距离的, 如果传入的参数长度不对, 会抛出数组越界异常
     *
     * @param id
     * @param id2
     * @return
     */
    public static byte[] distance(byte[] id, byte[] id2) {
        byte[] ret = new byte[20];
        for (int i = 0; i < 20; i++) {
            ret[i] = (byte)(id[i] ^ id2[i]);
        }
        return ret;
    }

    /**
     * 根据距离的计算桶的key值
     *
     * @param id
     * @param id2
     * @return
     */
    public static int distanceK(BeString id, BeString id2) {
        return distanceK(id.getValue(), id2.getValue());
    }

    /**
     * 根据距离的计算桶的key值
     *
     * @param id
     * @param id2
     * @return
     */
    public static int distanceK(byte[] id, byte[] id2) {
        byte[] distance = distance(id, id2);
        int k = 0;
        for (byte d : distance) {
            if (d == 0) {
                k += 8;
            } else {
                for (int i = 0; i < 9; i++) {
                    int d1 = d >>> i;
                    if (d1 == 0) {
                        k = k + 8 - i;
                    }
                }
            }
        }
        return k;
    }

    public static class DefaultThreadFactory implements ThreadFactory {

        private ThreadGroup threadGroup;

        public DefaultThreadFactory(ThreadGroup threadGroup) {
            this.threadGroup = threadGroup;
        }

        public DefaultThreadFactory(String threadGroupName) {
            this(new ThreadGroup(threadGroupName));
        }

        public Thread newThread(String name, Runnable r) {
            Thread thread = newThread(r);
            thread.setName(name);
            return thread;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(threadGroup, r);
            return thread;
        }
    }

    public static void main(String[] args) throws IOException {
        ConcurrentHashMap<Integer,String> map=new ConcurrentHashMap<>();

        map.put(1,"1");
        map.put(2,"2");
        map.put(3,"3");

        map.entrySet().iterator().remove();


        System.out.println(map.size());

    }

}
